package cn.genmer.skywalking.plugins.springmvc;

import org.apache.skywalking.apm.agent.core.context.ContextManager;
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.apache.skywalking.apm.dependencies.org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SpringMVCParamsInterceptor implements InstanceMethodsAroundInterceptor {

    public SpringMVCParamsInterceptor() {
        System.out.println(">>> SpringMVCParamsInterceptor 构造被调用！");
    }

    // 从JVM参数读取配置
    private static final long TIME_THRESHOLD = Long.getLong(
        "skywalking.plugin.springmvc.time_threshold", 150); // 默认500ms


    @Override
    public void beforeMethod(EnhancedInstance objInst, Method method,
                             Object[] allArguments, Class<?>[] argumentsTypes,
                             MethodInterceptResult result) {
        System.out.println("before11111");
        System.out.println("[拦截器] classloader=" + this.getClass().getClassLoader());

        // 创建 LocalSpan
        String className = method.getDeclaringClass().getName();
        String methodName = method.getName();
        AbstractSpan span = ContextManager.createLocalSpan(className + "/"+methodName);
        span.tag("params", "2222");
        objInst.setSkyWalkingDynamicField(System.currentTimeMillis());
    }

    @Override
    public Object afterMethod(EnhancedInstance objInst, Method method,
                              Object[] allArguments, Class<?>[] argumentsTypes,
                              Object ret) throws Throwable {

        AbstractSpan span = ContextManager.activeSpan();
        if(span != null){
            // 标准标签注入
            span.tag("params", "1111");
            span.tag("custom_field", "test_value");

            // 调试日志
            span.log(new RuntimeException("test log"));
        } else {
            LoggerFactory.getLogger(getClass())
                    .warn("No active span detected");
        }

        Long startTime = (Long) objInst.getSkyWalkingDynamicField();
        // if (startTime == null) return ret;


        long cost = System.currentTimeMillis() - startTime;
        System.out.println("[拦截器] cost=" + cost);
        // long cost = 0;
        if (cost > TIME_THRESHOLD) {
            try {

                // HttpServletRequest request = ((ServletRequestAttributes)
                //         RequestContextHolder.currentRequestAttributes()).getRequest();

                if (span != null) {
                    span.tag("slow_params",
                            String.format("cost=%dms|params=%s",
                                    cost,
                                    "测试固定参数address: = 浙江省杭州桐庐县"));
                                    // request.getQueryString()));
                }
            } catch (Exception e) {
                // 静默处理避免影响业务
            }
        }

        // 结束 LocalSpan
        ContextManager.stopSpan();
        return ret;
    }

    @Override
    public void handleMethodException(EnhancedInstance enhancedInstance, Method method, Object[] objects, Class<?>[] classes, Throwable throwable) {
        AbstractSpan span = ContextManager.activeSpan();
        if (span != null) {
            span.log(throwable);
            span.errorOccurred();
        }
    }
}
